﻿Imports System
Imports System.Runtime.InteropServices
Imports System.Windows.Forms.Design
Imports System.ComponentModel
Imports System.Windows.Forms.Design.Behavior
Imports System.Windows.Forms
Imports System.Drawing
Imports System.Collections

Public Class NIB_ControlDesigner
    Inherits ControlDesigner

    Public Overrides ReadOnly Property SelectionRules() As SelectionRules
        Get

            Return Windows.Forms.Design.SelectionRules.Moveable Or _
                   Windows.Forms.Design.SelectionRules.LeftSizeable Or _
                   Windows.Forms.Design.SelectionRules.RightSizeable
        End Get
    End Property

    Public Overrides ReadOnly Property SnapLines() As IList
        Get
            Dim _snapLines As ArrayList = TryCast(MyBase.SnapLines, ArrayList)
            Dim textBaseline As Int32 = GetTextBaseline(Me.Control, ContentAlignment.TopLeft)
            Dim style As BorderStyle = BorderStyle.Fixed3D
            Dim descriptor As PropertyDescriptor = TypeDescriptor.GetProperties(MyBase.Component).Item("BorderStyle")
            If (Not descriptor Is Nothing) Then
                style = DirectCast(descriptor.GetValue(MyBase.Component), BorderStyle)
            End If
            If (style = BorderStyle.None) Then
                textBaseline = textBaseline
            ElseIf (style = BorderStyle.FixedSingle) Then
                textBaseline = textBaseline + 2 '(SystemInformation.BorderSize.Height * 2)
            ElseIf (style = BorderStyle.Fixed3D) Then
                textBaseline = textBaseline + 3 '(SystemInformation.Border3DSize.Height * 2)
            Else
                textBaseline = textBaseline
            End If
            _snapLines.Add(New SnapLine(SnapLineType.Baseline, _
                                        textBaseline, _
                                        SnapLinePriority.Medium))
            Return _snapLines
        End Get
    End Property

   Public Shared Function GetTextBaseline(ByVal ctrl As Control, ByVal alignment As ContentAlignment) As Int32
      ' For text metrics reference, see: FontHeightLayout1.bmp

      Dim clientRectangle As Rectangle = ctrl.ClientRectangle
      Dim charHeight As Int32 = 0
      'Dim tmHeight As Int32 = 0
      Dim tm As New TEXTMETRIC

      Using graphics As Graphics = ctrl.CreateGraphics
         Dim hdc As IntPtr = graphics.GetHdc
         Dim handle As IntPtr = ctrl.Font.ToHfont
         Try
            Dim hdlOldHDC As IntPtr = SelectObject(New HandleRef(ctrl, hdc), New HandleRef(ctrl, handle))
            GetTextMetrics(New HandleRef(ctrl, hdc), tm)
            charHeight = (tm.tmAscent + 1)
            SelectObject(New HandleRef(ctrl, hdc), New HandleRef(ctrl, hdlOldHDC))
         Finally
            DeleteObject(New HandleRef(ctrl.Font, handle))
            graphics.ReleaseHdc(hdc)
         End Try
      End Using
      Select Case alignment
         Case ContentAlignment.TopLeft, ContentAlignment.TopCenter, ContentAlignment.TopRight
            Return (clientRectangle.Top + charHeight)

         Case ContentAlignment.MiddleLeft, ContentAlignment.MiddleRight, ContentAlignment.MiddleRight
            Return (((clientRectangle.Top + (clientRectangle.Height \ 2)) - (tm.tmHeight \ 2)) + charHeight)

         Case Else 'Bottom or undefined
           Return ((clientRectangle.Bottom - tm.tmHeight) + charHeight)

      End Select

    End Function

   <DllImport("gdi32.dll", CharSet:=CharSet.Auto, ExactSpelling:=True)> _
   Public Shared Function SelectObject(ByVal hDC As HandleRef, ByVal hObject As HandleRef) As IntPtr
   End Function

   <DllImport("gdi32.dll", CharSet:=CharSet.Auto)> _
   Public Shared Function GetTextMetrics(ByVal hdc As HandleRef, ByVal tm As TEXTMETRIC) As Boolean
   End Function

   <DllImport("gdi32.dll", CharSet:=CharSet.Auto, SetLastError:=True, ExactSpelling:=True)> _
   Public Shared Function DeleteObject(ByVal hObject As HandleRef) As Boolean
   End Function

   <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
   Public Class TEXTMETRIC
       Public tmHeight As Int32
       Public tmAscent As Int32
       Public tmDescent As Int32
       Public tmInternalLeading As Int32
       Public tmExternalLeading As Int32
       Public tmAveCharWidth As Int32
       Public tmMaxCharWidth As Int32
       Public tmWeight As Int32
       Public tmOverhang As Int32
       Public tmDigitizedAspectX As Int32
       Public tmDigitizedAspectY As Int32
       Public tmFirstChar As Char
       Public tmLastChar As Char
       Public tmDefaultChar As Char
       Public tmBreakChar As Char
       Public tmItalic As Byte
       Public tmUnderlined As Byte
       Public tmStruckOut As Byte
       Public tmPitchAndFamily As Byte
       Public tmCharSet As Byte
   End Class

End Class

